package com.hw.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * NIO的服务端：阻塞和非阻塞模式
 * @program: NIO_Netty
 * @author: hewei
 * @date: 2023-03-31 11:42
 **/
public class ChannelServer {

    public static void main(String[] args) throws IOException {

        Long timestamp=System.currentTimeMillis();
        ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
        Charset charset = Charset.forName("UTF-8");
        List<SocketChannel> socketList=new ArrayList<>();
        try (ServerSocketChannel serverSocketChannel = ServerSocketChannel.open()){
            serverSocketChannel.bind(new InetSocketAddress(9696));
            /*设置 serverSocketChannel模式为非阻塞，默认是阻塞模式*/
            serverSocketChannel.configureBlocking(false);

            while (true){
                 /*非阻塞模式：线程还会继续运行，如果没有连接建立，serverSocketChannel.accept() 返回 null。（如果是阻塞模式：线程会暂停）*/
                SocketChannel socketChannel=serverSocketChannel.accept();
                /*成功接受到客户端连接后执行*/
                if (socketChannel != null) {
                    /*设置 SocketChannel 模式为非阻塞，默认为阻塞 */
                    socketChannel.configureBlocking(false);
                    socketList.add(socketChannel);
                    buffer.put(("你好，这是服务端！"+timestamp).getBytes(StandardCharsets.UTF_8));
                    /*读写模式的切换*/
                    buffer.flip();
                    socketChannel.write(buffer);
                    System.out.println("Server send：你好，这是服务端！");
                    buffer.clear();
                }

                for (SocketChannel channel : socketList) {
                    /*非阻塞模式：线程仍然会继续运行，如果没有读到数据，read 返回 0。（如果是阻塞模式：线程会暂停）*/
                    if (channel.read(buffer) ==0 ){
                        continue;
                    }
                    buffer.flip();
                    System.out.println("Server received："+"["+channel.getRemoteAddress()+"]"+ charset.decode(buffer));
                    buffer.clear();
                }
            }
        }finally {
            socketList.clear();
        }

    }
}
